#include "databaseprivate.h"
#include <QSqlError>
#include <QSqlQuery>
#include <QVariant>
#include <QDebug>
#include "common_log.h"

DataBasePrivate::DataBasePrivate()
{


}

DataBasePrivate::~DataBasePrivate()
{}

bool DataBasePrivate::InitDB(const QString& path)
{
	if (path.isEmpty()) {
		log_error("path is null, init failed");
		return false;
	}

	m_db = QSqlDatabase::addDatabase("QSQLITE", "VISDB");
	m_db.setDatabaseName(path);
	if (m_db.open()) {
		log_trace("{} sql open successed", path);
		return true;
	}

	log_error("{} sql open failed");
	return false;
}
int DataBasePrivate::GetTabDataSize(const QString& tablename)
{
	if (!IfTableExist(tablename)) {
		log_error("[{}] is not exist", tablename);
		return -1;
	}

	QString sql = "SELECT COUNT(*) FROM " + tablename;
	QSqlQuery qurry(m_db);
	if (!qurry.exec(sql)) {
		log_error("exec error: {}", qurry.lastError().text());
		return -1;
	}
	int count = qurry.value(0).toInt();
	return count;

}
bool DataBasePrivate::InsertDataByID(const QString& tablename, int id, QStringList& key, QStringList& val)
{
	log_trace("insert data  to table [{}], id = {}", tablename, id);

	if (!IfTableExist(tablename)) {
		log_error("{} not exit", tablename);
		return false;
	}
	if (key.size() != val.size()) {
		log_error("data size not equal to val size");
		return false;
	}

	QString sql = "INSERT INTO " + tablename + " ( id,";
	for (int i = 0; i < key.size(); i++) {
		sql += key[i];
		if (i == key.size() - 1) {
			sql += QString(") ");
		} else {
			sql += QString(",");
		}
	}
	sql += QString("VALUES(") + QString::number(id) + ",\'";
	for (int i = 0; i < val.size(); i++) {
		sql += val[i];
		if (i == val.size() - 1) {
			sql += QString("\')");
		} else {
			sql += QString("\', ");
		}
	}
	QSqlQuery qurry(m_db);
	if (!qurry.exec(sql)) {
		log_error("exec error: {}", qurry.lastError().text());
		return false;
	}
	return true;
}
bool DataBasePrivate::DeleteAllData(const QString& tablename)
{
	log_trace("Delete all data for [{}]", tablename);
	if (!IfTableExist(tablename)) {
		log_error("{} not exit", tablename);
		return false;
	}
	rw_lock.lockForWrite();
	QString sql = "DELETE FROM " + tablename;
	QSqlQuery qurry(m_db);
	if (!qurry.exec(sql)) {
		rw_lock.unlock();
		log_error("exec error: {}", qurry.lastError().text());
		return false;
	}
	rw_lock.unlock();
	return true;
}
bool DataBasePrivate::DeleteDataByID(const QString& tablename, int id)
{
	log_trace("Delet data [{}] form [{}]", id, tablename);
	if (!IfTableExist(tablename)) {
		log_error("{} not exit", tablename);
		return false;
	}
	rw_lock.lockForWrite();
	QString sql = "DELETE FROM " + tablename + " WHERE id = " + QString::number(id);
	QSqlQuery qurry(m_db);
	if (!qurry.exec(sql)) {
		rw_lock.unlock();
		log_error("exec error: {}", qurry.lastError().text());
		return false;
	}
	rw_lock.unlock();
	return true;
}
bool DataBasePrivate::UpdataDataByID(const QString& tablename, int id, QStringList& key, QStringList& val)
{
	rw_lock.lockForWrite();
	if (key.size() != val.size()) {
		log_error("size error", tablename);
		return false;
	}
	if (!IfTableExist(tablename)) {
		log_error("{} not exit", tablename);
		return false;
	}

	QString sql = "UPDATE " + tablename + " SET ";
	for (int i = 0; i < key.size(); i++) {
		sql += key[i];
		sql += " = ";
		sql += ("'" + val[i] + "'");

		if (i < key.size() - 1) {
			sql += ",";
		}
	}
	sql += (" WHERE id = " + QString::number(id));
	QSqlQuery qurry(m_db);
	if (!qurry.exec(sql)) {
		rw_lock.unlock();
		log_error("exec error: {}", qurry.lastError().text());
		return false;
	}
	rw_lock.unlock();
	return true;
}
bool DataBasePrivate::IfTableHasId(const QString& tablename, int id)
{
	rw_lock.lockForWrite();

	//if (!IfTableExist(tablename)) {
	//	log_error("{} not exit", tablename);
	//	return false;
	//}

	QString sql = "SELECT * FROM " + tablename + " activity ";
	sql += (" WHERE id = " + QString::number(id) + " LIMIT 1");
	QSqlQuery qurry(m_db);
	if (!qurry.exec(sql)) {
		rw_lock.unlock();
		log_error("exec error: {}", qurry.lastError().text());
		return false;
	}
	rw_lock.unlock();
	if (qurry.next()) {
		return qurry.value(0).toInt() > 0;
	}
	return false;
}
bool DataBasePrivate::IfTableExist(const QString& tablename)
{
	return m_db.tables().contains(tablename, Qt::CaseInsensitive);
}
bool DataBasePrivate::CreatTable(const QString& tablename, QStringList& key, QStringList& type)
{
	log_trace("Create Table[{}]", tablename);
	if (key.size() != type.size()) {
		return false;
	}

	if (!m_db.isOpen()) {
		log_error("DB not opened");
		return false;
	}

	if (IfTableExist(tablename)) {
		QSqlRecord rr = m_db.record(tablename);
		QStringList nkey;
		QStringList ntype;
		QString sql;
		int index = 0;
		for (; index < key.size(); index++) {
			if (!rr.contains(key[index])) {
				if (index < type.size()) {
					sql = QString("ALTER TABLE ") + tablename + QString(" add column ");
					sql += key[index];
					sql += " ";
					sql += type[index];
					nkey << key[index];
					ntype << type[index];
					QSqlQuery qurry(m_db);
					if (!qurry.exec(sql)) {
						return false;
					}
				}
			}
		}
		return true;
	}
	QString sql = QString("CREATE TABLE IF NOT EXISTS ") + tablename + QString("(");
	for (int i = 0; i < key.size(); i++) {
		sql += key[i];
		sql += QString(" ");
		sql += type[i];
		if (i == key.size() - 1) {
			sql += QString(") ");
		} else {
			sql += QString(",");
		}
	}
	QSqlQuery qurry(m_db);
	if (!qurry.exec(sql)) {
		log_error("exec error: {}", qurry.lastError().text());
		return false;
	}
	return true;
}

QStringList DataBasePrivate::ReadDataByID(const QString& tablename, int query, const QString& key)
{
	if (!IfTableExist(tablename)) {
		return {};
	}

	if (key.isEmpty()) {
		return {};
	}

	rw_lock.lockForRead();

	QString sql = "SELECT * FROM " + tablename;
	if (query >= 0) {
		sql += " WHERE id = ";
		sql += QString::number(query);
	}


	QSqlQuery qurry(m_db);
	if (!qurry.exec(sql)) {
		log_error("exec error: {}", qurry.lastError().text());
		return {};
	}
	QStringList ret;
	while (qurry.next()) {
		if (query > 0) {
			if (qurry.value("id").toInt() == query) {
				ret.push_back(qurry.value(key).toString());
			}
		} else {
			ret.push_back(qurry.value(key).toString());
		}
	}

	rw_lock.unlock();
	return ret;
}
